/*
 * -----------需要坐标系的
 * Line            折线图
 * Bar             柱状图
 * Scatter         散点（气泡）图
 * effectScatter   带有涟漪特效动画的散点（气泡）图
 * Heatmap         热力图
 * Candlestick     K 线图
 * Boxplot         盒须图
 * PictorialBar    象形柱图
 * -----------不需要坐标系的
 * Pie             饼图
 * Tree            树图
 * Treemap         矩形树图
 * Radar           雷达图
 * Sunburst        旭日图
 * Map             地图
 * Parallel        平行坐标系
 * Lines           路径图
 * Sankey          桑基图
 * Funnel          漏斗图
 * Gauge           仪表盘
 * ThemeRiver      主题河流图
 * ------------既可以又不 坐标系的
 * Graph           关系图
*/



var myChart;
function loadEchart(domId, options){
    if(options.type === 'table' || options.type === 'cross_table'){
        return loadEchart._loadETable(domId, options);
    }
    return loadEchart._loadEchart(domId, options);
}

loadEchart._loadEchart = function(domId, options){

    var def = {
        ////类型选择：bar、line、pie、Scatter、effectScatter、Heatmap、Candlestick、Boxplot、PictorialBar、Tree、Treemap、Radar、Sunburst、Map、Parallel、Lines、Sankey、Funnel、Gauge、ThemeRiver、Graph
        type: 'bar',

        ////主题选择:
        //内置：不设=默认, light, dark;
        //扩展: macarons, macarons2, infographic, shine, roma, azul, fruit, forest, eduardo, carp, caravan, vintage, cool, sakura, royal, mint, london, jazz, helianthus, inspired, bee-inspired, green, gray, blue, red, red-velvet, tech-blue, fresh-cut, dark-mushroom, dark-fresh-cut, dark-digerati, dark-bold, dark-blue
        // theme: 'light',

        ////全局的调色盘颜色列表
        // color: '#c23531,#2f4554,#61a0a8,#d48265,#91c7ae,#749f83,#ca8622,#bda29a,#6e7074,#546570,#c4ccd3',

        ////全局的背景色
        backgroundColor: 'transparent',

        ////全局的字体样式
        //取值：color:#fff|fontStyle:normal|fontWeight:normal|fontFamily:sans-serif|fontSize:12|lineHeight:12|width:20|height:21|textBorderColor:transparent|textBorderWidth:2|textShadowColor:transparent|textShadowBlur:5|textShadowOffsetX:5|textShadowOffsetY:5
        textStyle: '',

        ////是否显示loading
        ifShowLoading: true,

        //// 标题设置 ------------------------------
        //标题
        title: '',
        //是否显示
        titleShow: true,
        //标题样式。取值：textAlign:auto|textVerticalAlign:auto|padding:5|itemGap:10|zlevel:1|z:3|left:50|top:auto|right:auto|bottom:auto|backgroundColor:transparent|borderColor:#ccc|borderWidth:5|borderRadius:5|shadowBlur:5|shadowColor:#ccc|shadowOffsetX:2|shadowOffsetY:2
        titleStyle: '',
        //标题位置。取值：top_left、top_center、top_right、middle_left、middle_center、middle_right、bottom_left、bottom_center、bottom_right
        //如果位置在titleStyle里有left，right，bottom，top之类的设置，titleStyle里的优先，以便更精细的控制位置
        titlePosition: '',
        //标题文字样式。取值：color:#333|fontStyle:normal|fontWeight:normal|fontFamily:Source Sans Pro|fontSize:18|lineHeight:18|textBorderColor:transparent ...
        titleTextStyle: '',
        //副标题
        titleSub: '',
        //副标题样式。取值：color:#333|fontStyle:normal|fontWeight:normal|fontFamily:Source Sans Pro|fontSize:18|lineHeight:18|textBorderColor:transparent ...
        titleSubTextStyle: '',

        //// 图例设置 ------------------------------
        //是否显示。此项的优先级为：options>本方法内调度>默认值（无设置）
        //legendShow: false,
        //图例类型：取值：plain、scroll
        legendType: 'plain',
        //图例样式。取值：zlevel:1|z:3|left:auto|top:auto|right:auto|bottom:auto|width:auto|height:auto|orient:horizontal|align:auto|padding:5|itemGap:5|itemWidth:25|itemHeight:14|inactiveColor:#ccc|backgroundColor:transparent|borderColor:#ccc|borderWidth:1|borderRadius:5|shadowBlur:5|shadowColor:#ccc|shadowOffsetX:5|shadowOffsetY:8|scrollDataIndex:5|pageButtonItemGap:5|pageButtonGap:5|pageButtonPosition:end
        legendStyle: '',
        //图例位置。取值：top_left、top_center、top_right、middle_left、middle_center、middle_right、bottom_left、bottom_center、bottom_right
        //如果位置在legendStyle里有left，right，bottom，top之类的设置，legendStyle里的优先，以便更精细的控制位置
        legendPosition: '',
        //图例方向。取值：horizontal、vertical
        //如果布局朝向在legendStyle里有orient设置，lenendOrient里的优先
        lenendOrient: 'horizontal',
        //图例formatter
        legendFormatter: '',
        //图例***
        legendSelectedMode: true,
        //图例文字样式。取值：color:#ccc|fontStyle:normal|fontWeight:normal|fontFamily:sans-serif|fontSize:12|lineHeight:20|backgroundColor:transparent|borderColor:transparent|borderWidth:9|borderRadius:10|padding:5|width:50|height:50...
        legendTextStyle: '',

        ////// x轴设置 ------------------------------
        //是否显示。此项的优先级为：options>本方法内调度>默认值（无设置）
        //xAxisShow: true,

        ////// y轴设置 ------------------------------
        //是否显示。此项的优先级为：options>本方法内调度>默认值（无设置）
        //yAxisShow: true,

        //// 座标盘设置 ------------------------------
        //是否显示
        gridShow: false,

        //// 鼠标提示设置 ------------------------------
        //是否显示
        tooltipShow: true,

        //// 工具组件设置 ------------------------------
        //是否显示
        toolboxShow: false

    };
    var opt = Object.assign({}, def, options);

    var _title = {}, _legend = {}, _grid = {}, _xAxis = {}, _yAxis = {}, _tooltip = {}, _toolbox = {};

    //// _title ------------------------------
    Object.assign(_title, {
        text: opt.title,
        show: opt.titleShow
    });
    //如果titlePosition有设置 && titleStyle里没有出现left,right,bottom,top设置字符串，则取titlePosition的
    //翻译：标题位置优先级：titleStyle里设置 > titlePosition > echart默认
    if(opt.titlePosition!=='' && !/(left\s*:)|(right\s*:)|(bottom\s*:)|(top\s*:)/.test(opt.titleStyle)){
        var v = {};
        if(opt.titlePosition.indexOf('top')>-1) v.top = 'top';
        if(opt.titlePosition.indexOf('middle')>-1) v.top = 'middle';
        if(opt.titlePosition.indexOf('bottom')>-1) v.top = 'bottom';
        if(opt.titlePosition.indexOf('left')>-1) v.left = 'left';
        if(opt.titlePosition.indexOf('center')>-1) v.left = 'center';
        if(opt.titlePosition.indexOf('right')>-1) v.left = 'right';
        Object.assign(_title, v);
    }
    Object.assign(_title, getObjFromString(opt.titleStyle));
    Object.assign(_title, {textStyle: getObjFromString(opt.titleTextStyle)});
    if(opt.titleSub != ''){
        _title.subtext = opt.titleSub;
        Object.assign(_title, {subtextStyle: getObjFromString(opt.titleSubTextStyle)});
    }

    //// _legend ------------------------------
    Object.assign(_legend, {
        type: opt.legendType,
        selectedMode: opt.legendSelectedMode
    });
    //如果legendPosition有设置 && legendStyle里没有出现left,right,bottom,top设置字符串，则取legendPosition的
    //翻译：图例位置优先级：legendStyle里设置 > legendPosition > echart默认
    if(opt.legendPosition!=='' && !/(left\s*:)|(right\s*:)|(bottom\s*:)|(top\s*:)/.test(opt.legendStyle)){
        var v = {};
        if(opt.legendPosition.indexOf('top')>-1) v.top = 'top';
        if(opt.legendPosition.indexOf('middle')>-1) v.top = 'middle';
        if(opt.legendPosition.indexOf('bottom')>-1) v.top = 'bottom';
        if(opt.legendPosition.indexOf('left')>-1) v.left = 'left';
        if(opt.legendPosition.indexOf('center')>-1) v.left = 'center';
        if(opt.legendPosition.indexOf('right')>-1) v.left = 'right';
        Object.assign(_legend, v);
    }
    Object.assign(_legend, getObjFromString(opt.legendStyle));
    Object.assign(_legend, {textStyle: getObjFromString(opt.legendTextStyle)});
    //如果布局朝向在legendStyle里有orient设置，lenendOrient里的优先 (覆盖上面)
    _legend.orient = opt.lenendOrient;
    if(opt.legendFormatter != '') _legend.formatter = opt.legendFormatter;

    //// _tooltip  ------------------------------
    _tooltip.show = opt.tooltipShow;

    //// _tooltip  ------------------------------
    _tooltip.show = opt.tooltipShow;

    //// _toolbox  ------------------------------
    _toolbox.show = opt.toolboxShow;



    var shouldHasXY = ['line','bar','scatter','effectScatter','heatmap','candlestick','boxplot','pictorialBar','graph'].some(function(v){ return v == opt.type; });

    if('xAxisShow' in opt) _xAxis.show = opt.xAxisShow;
    else _xAxis.show = shouldHasXY;

    if('yAxisShow' in opt) _xAxis.show = opt.yAxisShow;
    else _yAxis.show = shouldHasXY;

	// 解决echarts dom已经加载的报错 02-24-tgrong
    if(myChart != null && myChart != "" && myChart != undefined){
    	myChart.dispose();
    }

    myChart = echarts.init(document.getElementById(domId), opt.theme);
    myChart.setOption({
        // color: opt.color.split(','),
        backgroundColor: opt.backgroundColor,
        textStyle: getObjFromString(opt.textStyle),
        title: _title,
        legend: _legend,
        grid: _grid,
        xAxis: _xAxis,
        yAxis: _yAxis,
        tooltip: _tooltip,
        toolbox: _toolbox
    });

    opt.ifShowLoading && myChart.showLoading();

    return setEchart;

    function setEchart(data, dataSet, params){
        params = params || {};
        /*params:
            {
                // 20%,13%-23%||50%,75%-50%： 第一个pie的半径为20%，圆心位置x为13%，y为23%；第二个pie的半径为50% ...
                pieSizePosition: 'none' 或者 '50%,25%-50%||50%,75%-50%||...' 或者 '200,25%-50%||50%,100-50%||...'
            }
        */
        myChart.hideLoading();
        var data = dataFmt(data);
        var layers = param2fmt(dataSet);
        var option = {legend: {}};

        var xOrders = layers.categorys.map(function(v){ return v.replace('s', '') * 1; });
        var yOrders = layers.values.map(function(v){ return v.replace('s', '') * 1; });

        //如果legend的显或隐在options里设，则取options里的。否则：列数为一时，不显示，大于一时，显示
        if('legendShow' in opt){
            option.legend.show = opt.legendShow;
        }else{
            option.legend.show = yOrders.length > 1
        }

        if(opt.type === 'bar' || opt.type === 'line'){
            option.xAxis = {
                type: 'category',
                data: getColData(data, xOrders[0])
            };
            option.series = yOrders.map(function(v){
                return {
                    name: data.firstRow[v-1],
                    type: opt.type,
                    data: getColData(data, v)
                };
            });
        }else if(opt.type === 'pie'){
            option.legend.data = data.firstRow.filter(function(v, i){ return yOrders.indexOf(i*1+1)>-1 }).map(function(v){ return {name: v} });
            var names = getColData(data, xOrders[0]);
            //每个pie的大小和位置（尤其是在当pie的列数大于1时会很重要）：如果在params里有设pieSizePosition，则取params设置。否则取mm默认
            //目前mm默认里只设置了1-4个，大于4个请务必提供params.pieSizePosition
            //mm默认:
            var mmAuto = {
                '1': 'none',
                '2': '50%,25%-50%||50%,75%-50%',
                '3': '25%,25%-30%||25%,75%-30%||25%,25%-70%',
                '4': '25%,25%-30%||25%,75%-30%||25%,25%-70%||25%,75%-70%',
            };
            var pieSzPs = params.pieSizePosition || mmAuto[yOrders.length] || 'none';
            pieSzPs = pieSzPs.split('||');
            pieSzPs = pieSzPs.map(function(v){
                if(v === 'none') return 'none';
                var a = v.split(','), s1 = a[0], b = a[1].split('-'), s2 = b[0], s3 = b[1];
                var arr = [s1, s2, s3];
                return arr.map(function(vv){
                    return (/^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(vv)) ? vv * 1 : vv;
                });
            });

            option.series = yOrders.map(function(v, mi){
                var values = getColData(data, v);
                var items = values.map(function(v, i){
                    return { name: names[i], value: v };
                });
                var b = {
                    name: data.firstRow[v-1],
                    type: opt.type,
                    data: items
                };
                var szps = pieSzPs[mi] || 'none';
                if(szps!=='none'){
                    b.radius = szps[0];
                    b.center = [szps[1], szps[2]]
                }
                return b;
            });
        }

        myChart.setOption(option);
        return myChart;
    };
    function getObjFromString(str){
        str = str.replace(/(^\s*)|(\s*$)/g, '').replace(/(^\|)|(\|$)/g, '');
        var obj = {};
        if(str == '') return obj;
        var arr = str.split('|');
        for(var i=0,len=arr.length;i<len;i++){
            var item = arr[i].replace(/(^\s*)|(\s*$)/g, '');
            var lr = item.split(':');
            var l = lr[0].replace(/(^\s*)|(\s*$)/g, '');
            var r = (lr[1]||'').replace(/(^\s*)|(\s*$)/g, '');
            var val = /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(r) ? r * 1 : r;
            obj[l] = val;
        }
        return obj;
    }
    function param2fmt(obj){
        var categorys = [obj.category];
        var values = [obj.value];
        for(var i=2; i<9999; i++){
            if('category'+i in obj) categorys.push(obj['category'+i]);
            if('value'+i in obj) values.push(obj['value'+i]);
            if(!('category'+i in obj) && !('value'+i in obj)) break;
        }
        return {
            categorys: categorys,
            values: values
        };
    }
    function dataFmt(data){
        var datas = data.data.map(function(v){
            var arr = [];
            for(var i=1; i<=data.define.ColCount; i++) arr.push(v['s'+i]);
            return arr;
        });
        var first = datas.shift();
        return {
            colCount: data.define.ColCount,
            datas: datas,
            firstRow: first
        };
    }
    function getColData(data, userIndex){
        return data.datas.map(function(v){
            return v[userIndex - 1];
        });
    }
}

loadEchart._loadETable = function(domId, options){
    return function(data, dataSet, params){
        var opt = $.extend({}, {
            moreColsFullWidth: 4,
            minColWidth: 90
        }, params);
        data.define = data.define || {};
        var numTop = data.define.RowTitleCount||0,
            numBtm = data.define.RowTotalCount||0,
            numLt = data.define.ColTitleCount||0,
            numRt = data.define.ColTotalCount||0;
        var theadData = data.data.slice(0, numTop);
        var tbodyData = data.data.slice(numTop, data.data.length-numBtm);
        var tfootData = data.data.slice(data.data.length-numBtm);
        var theadArr = theadData.map(function(row){
            var tds = [];
            for(var i=1; i<=numLt; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<th class="leftit'+hdClass+'"><div class="stats-thdiv">'+ con +'</div></th>';
                tds.push(td);
            }
            for(var i=numLt+1; i<=data.define.ColCount-numRt; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<th class="'+hdClass+'"><div class="stats-thdiv">'+ con +'</div></th>';
                tds.push(td);
            }
            for(var i=data.define.ColCount-numRt+1; i<=data.define.ColCount; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<th class="rightit'+hdClass+'"><div class="stats-thdiv">'+ con +'</div></th>';
                tds.push(td);
            }
            return `<tr>${tds.join('\n')}</tr>`;
        });
        var tbodyArr = tbodyData.map(function(row){
            var tds = [];
            for(var i=1; i<=numLt; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<td class="leftit'+hdClass+'">'+ con +'</td>';
                tds.push(td);
            }
            for(var i=numLt+1; i<=data.define.ColCount-numRt; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<td class="'+hdClass+'">'+ con +'</td>';
                tds.push(td);
            }
            for(var i=data.define.ColCount-numRt+1; i<=data.define.ColCount; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<td class="rightit'+hdClass+'">'+ con +'</td>';
                tds.push(td);
            }
            return `<tr>${tds.join('\n')}</tr>`;
        });
        var tfootArr = tfootData.map(function(row){
            var tds = [];
            for(var i=1; i<=numLt; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<td class="leftit'+hdClass+'">'+ con +'</td>';
                tds.push(td);
            }
            for(var i=numLt+1; i<=data.define.ColCount-numRt; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<td class="'+hdClass+'">'+ con +'</td>';
                tds.push(td);
            }
            for(var i=data.define.ColCount-numRt+1; i<=data.define.ColCount; i++){
                var con = (('s'+i) in row) ? row['s'+i] : '';
                var hdClass = (typeof data.define.Titles==='object' && data.define.Titles['s'+i].Hide == 1) ? ' rowhide' : '';
                //临时：
                if(data.define.SelDataType == 'cross') hdClass = '';
                var td = '<td class="rightit'+hdClass+'">'+ con +'</td>';
                tds.push(td);
            }
            return `<tr>${tds.join('\n')}</tr>`;
        });
        var inner = `<thead>${theadArr.join('\n')}</thead><tbody>${tbodyArr.join('\n')}</tbody><tfoot>${tfootArr.join('\n')}</tfoot>`;
        var $table = $('#'+domId).html(`<div class="vj-stats"><table class="table table-hover table-bordered">${inner}</table></div>`)
            .find('.vj-stats').css({overflow: 'auto', height: '100%'})
            .find('table').css({width: data.define.ColCount>opt.moreColsFullWidth?'auto': '100%', marginBottom:0});
            $table.find('.stats-thdiv').css({minWidth: opt.minColWidth});
            $table.find('thead, tfoot').css('background', '#cacaca');
            $table.find('.leftit, .rightit').css('background', '#e4e4e4');
            $table.find('.rowhide').hide();
    };
}
